<template>
  <view class="dynamic-demo">

    <!-- 效果预览窗口 -->
    <view v-if="!noDemo" class="demo-container" :class="{'demo-container--full': full}">
      <view class="demo">
        <slot></slot>
      </view>
      <!-- 提示信息 -->
      <view v-if="haveTips">
        <view class="demo__tips__icon" @click="demoTipsClick">
          <view class="icon tn-icon-help"></view>
        </view>
        <view class="demo__tips__content"
          :class="[showContentTips ? 'demo__tips__content--show' : 'demo__tips__content--hide']">
          <view v-for="(item,index) in tipsData" :key="index" class="demo__tips__content--item">{{ item }}</view>
        </view>
      </view>
    </view>

    <!-- 模式切换 -->
    <view v-if="multiMode" class="mode-switch">
      <view class="mode-switch__container">
        <view v-for="(item, index) in sectionModeListInfos" :key="index" class="mode-switch__item"
          :class="[`mode-switch-item-${index}`,{'mode-switch__item--active': modeIndex === index}]"
          @click="switchMode(index)">{{ item.name }}</view>

        <!-- 滑块样式 -->
        <view class="mode-switch__slider" :style="[modeSwitchSliderStyle]"></view>
      </view>
    </view>

    <!-- 组件对应可选项容器 -->
    <view class="section-container">
      <scroll-view
        class="section__scroll-view"
        :class="{'section__scroll-view--auto': sectionScrollViewStyle.height === 'auto'}"
        :style="[sectionScrollViewStyle]"
        :scroll-y="sectionScrollViewStyle.height !== 'auto'"
      >
        <block v-for="(item,index) in btnsList" :key="index">
          <view class="section__content" :class="{'section__content--visible': item.show}">
            <view class="section__content__title">
              <view class="section__content__title__left-line" :class="[`tn-main-gradient-${tuniaoColorList[index]}`]"></view>
              <view class="section__content__title--text tn-text-ellipsis" :class="[`tn-main-gradient-${tuniaoColorList[index]}`]">{{ item.title }}</view>
              <view class="section__content__title__right-line" :class="[`tn-main-gradient-${tuniaoColorList[index]}`]"></view>
            </view>
            <view class="section__content__btns">
              <view v-for="(section_btn,section_index) in item.optional" :key="section_index"
                class="section__content__btns__item" :class="[`tn-main-gradient-${tuniaoColorList[index]}--light`]" @click="sectionBtnClick(index, section_index)">
                <view class="section__content__btns__item__bg"
                  :class="[`tn-main-gradient-${tuniaoColorList[index]}`, {'section__content__btns__item__bg--active':sectionIndex[modeIndex][index]['value'] === section_index}]"></view>
                <view class="section__content__btns__item--text tn-text-ellipsis"
                  :class="[sectionIndex[modeIndex][index]['value'] === section_index ? 'section__content__btns__item--text--active' : `tn-color-${tuniaoColorList[index]}`]">{{ section_btn }}</view>
              </view>
            </view>
          </view>
        </block>
      </scroll-view>
    </view>
  </view>
</template>

<script>
  export default {
    name: 'dynamic-demo-template',
    props: {
      // 可选项列表数据
      sectionList: {
        type: Array,
        default() {
          return []
        }
      },
      // 提示信息
      tips: {
        type: [String, Array],
        default: ''
      },
      // 演示框的内容是否为铺满
      full: {
        type: Boolean,
        default: false
      },
      // 是否使用了自定义顶部导航栏
      customBar: {
        type: Boolean,
        default: true
      },
      // 是否全屏滚动
      fullWindowsScroll: {
        type: Boolean,
        default: false
      },
      // 没有演示内容
      noDemo: {
        type: Boolean,
        default: false
      }
    },
    computed: {
      tipsData() {
        if (typeof this.tips === 'string') {
          return [this.tips]
        }
        return this.tips
      },
      haveTips() {
        return this.tips && this.tips.length > 0
      },
      multiMode() {
        return this.sectionList.length > 1
      },
      sectionModeList() {
        return this.sectionList.map((item) => {
          return item.name
        })
      }
    },
    data() {
      return {
        // 图鸟颜色列表
        tuniaoColorList: this.$tn.color.getTuniaoColorList(),
        // 保存选项列表信息（由于prop中的数据时不能被修改的）
        _sectionList: [],
        // 模式列表信息
        sectionModeListInfos: [],
        // 所选模式的序号
        modeIndex: 0,
        // 模式选择滑块样式
        modeSwitchSliderStyle: {
          width: 0,
          left: 0
        },
        // 显示组件相关提示信息
        showContentTips: false,
        // 可选项滚动容器样式
        sectionScrollViewStyle: {
          height: 0
        },
        // 按钮列表信息
        btnsList: [],
        // 标记当前所选按钮
        sectionIndex: [],
        // 标记选项按钮是否可以滑动（使用scroll-view进行包裹）
        sectionScrollFlag: true
      }
    },
    watch: {
      sectionList: {
        handler(value) {
          // 如果sectionList发生改变，重新初始化选项列表信息
          this.initSectionBtns()
        },
        deep: true
      },
      sectionScrollFlag(value) {
        if (!value) {
          this.sectionScrollViewStyle.height = 'auto'
        }
      },
      fullWindowsScroll: {
        handler(value) {
          if (value) {
            this.sectionScrollViewStyle.height = 'auto'
          }
        },
        immediate: true
      }
    },
    created() {
      // 初始化可选项模式列表
      this.sectionModeListInfos = this.sectionModeList.map((item) => {
        return {
          name: item
        }
      })
      // 初始化选项按钮默认信息
      this.initSectionBtns()
    },
    mounted() {
      // 等待加载组件完成
      // setTimeout(() => {
      //   // 计算出底部scroll-view的高度
      //   this.initSectionScrollView()

      //   if (this.multiMode) {
      //     // 获取模式切换标签的信息
      //     this.getModeTabsInfo()
      //   }
      // }, 10)
      this.$nextTick(() => {
        // 计算出底部scroll-view的高度
        this.initSectionScrollView()
        
        if (this.multiMode) {
          // 获取模式切换标签的信息
          this.getModeTabsInfo()
        }
      })
    },
    methods: {
      // 初始化选项滑动窗口的高度
      initSectionScrollView() {
        // 全屏滚动时不进行任何的操作
        if (this.fullWindowsScroll) {
          return
        }
        // 获取屏幕的高度
        uni.getSystemInfo({
          success: (systemInfo) => {
            // 通过当前屏幕的安全高度减去上一个元素的底部和距离上一个元素的外边距，然后减获取到的值减去标题栏的高度即可
            const navBarHeight = this.customBar ? 0 : this.vuex_custom_bar_height
            if (this.multiMode) {
              uni.createSelectorQuery().in(this).select('.mode-switch').boundingClientRect(data => {
                if (data.bottom >= systemInfo.safeArea.height) {
                  this.sectionScrollFlag = false
                } else {
                  this.sectionScrollFlag = true
                  const containerBaseHeight = systemInfo.safeArea.height - data.bottom
                  this.sectionScrollViewStyle.height = (containerBaseHeight - navBarHeight) + systemInfo.statusBarHeight - uni.upx2px(75) + 'px'
                }
              }).exec()
            } else {
              if (!this.noDemo) {
                uni.createSelectorQuery().in(this).select('.demo-container').boundingClientRect(data => {
                  if (data.bottom >= systemInfo.safeArea.height) {
                    this.sectionScrollFlag = false
                  } else {
                    this.sectionScrollFlag = true
                    const containerBaseHeight = systemInfo.safeArea.height - data.bottom
                    this.sectionScrollViewStyle.height = (containerBaseHeight - navBarHeight) + systemInfo.statusBarHeight - uni.upx2px(75) + 'px'
                  }
                }).exec()
              } else {
                this.sectionScrollFlag = false
              }
            }
            
          }
        })
      },
      // 更新选项滑动容器的高度
      updateSectionScrollView() {
        this.$nextTick(() => {
          this.initSectionScrollView()
        })
      },
      // 获取各个模式tab的节点信息
      getModeTabsInfo() {
        let view = uni.createSelectorQuery().in(this)
        for (let i = 0; i < this.sectionModeListInfos.length; i++) {
          view.select('.mode-switch-item-' + i).boundingClientRect()
        }
        view.exec(res => {
          // 如果没有获取到，则重新获取
          if (!res.length) {
            setTimeout(() => {
              this.getModeTabsInfo()
            }, 10)
            return
          }
          // 将每个模式的宽度放入list中
          res.map((item, index) => {
            this.sectionModeListInfos[index].width = item.width
          })
          // 初始化滑块的宽度
          this.modeSwitchSliderStyle.width = this.sectionModeListInfos[0].width + 'px'

          // 初始化滑块的位置
          this.modeSliderPosition()
        })
      },
      // 设置模式滑块的位置
      modeSliderPosition() {
        let left = 0
        // 计算当前所选模式选项到组件左边的距离
        this.sectionModeListInfos.map((item, index) => {
          if (index < this.modeIndex) left += item.width
        })

        this.modeSwitchSliderStyle.left = left + 'px'
      },
      // 切换模式
      switchMode(index) {
        // 不允许点击当前激活的选项
        if (index === this.modeIndex) return
        this.modeIndex = index
        this.modeSliderPosition()
        this.updateSectionBtns()
        this.$emit('modeClick', {
          index: index
        })
      },
      // 点击内容提示信息
      demoTipsClick() {
        this.showContentTips = !this.showContentTips
      },
      // 初始化被选中选项按钮
      initSectionBtns() {
        this.sectionIndex = []
        this.sectionIndex = this.sectionList.map((item) => {
          if (item.hasOwnProperty('section') && item.section.length > 0) {
            return Array(item.section.length).fill({
              value: 0,
              change: false
            })
          } else {
            return []
          }
        })
        
        this._sectionList = this.$tn.deepClone(this.sectionList)
        // 给本地选项按钮列表给默认show属性
        this._sectionList.map((item) => {
          const section = item.section.map((section_item) => {
            if (!section_item.hasOwnProperty('show')) {
              section_item.show = true
            }
            return section_item
          })
          item.section = section
          return item
        })
        
        // 更新按钮信息
        this.updateSectionBtns()
      },
      // 跟新选项按钮信息
      updateSectionBtns(sectionIndex = -1, showState = true) {
        let sectionOptional = this._sectionList[this.modeIndex]['section']
        this.btnsList = sectionOptional.map((item, index) => {
          // 判断是否已经修改了对应的值
          let changeValue = this.sectionIndex[this.modeIndex][index]['change'] || false
          let currentSectionIndexValue = this.sectionIndex[this.modeIndex][index]['value'] || 0
          // 取出默认值(如果是已经修改过的选项，则使用之前的选项信息)
          let indexValue = changeValue ? currentSectionIndexValue : item.hasOwnProperty('current') ? item.current : 0
          // 取出是否显示当前选项
          let show = (sectionIndex !== -1 && sectionIndex === index) ? showState : item.hasOwnProperty('show') ? item.show : true
          // 处理最大最小值
          if (indexValue < 0) {
            indexValue = 0
          }
          if (indexValue >= item.optional.length) {
            indexValue = item.optional.length
          }
          // this.sectionIndex[this.modeIndex][index]['value'] = indexValue
          this.$set(this.sectionIndex[this.modeIndex], index, {value: indexValue, change: changeValue})
          item.show = show
          return item
        })
      },
      // 更新选项按钮状态信息
      updateSectionBtnsState(sectionIndex = -1, showState = true) {
        // 判断sectionIndex是否为数组
        if (this.$tn.array.isArray(sectionIndex)) {
          if (sectionIndex.length === 0) {
            return
          }
          sectionIndex = sectionIndex.filter((item) => item >= 0 && item < this.sectionList[this.modeIndex]['section'].length)
          sectionIndex.map((item) => {
            this.btnsList[item]['show'] = showState
            this._sectionList[this.modeIndex]['section'][item]['show'] = showState
          })
        } else {
          if (sectionIndex < 0 || sectionIndex >= this.sectionList[this.modeIndex]['section'].length) {
            return
          }
          // 将按键的对应显示状态设置为对应的状态
          this.btnsList[sectionIndex]['show'] = showState
          this._sectionList[this.modeIndex]['section'][sectionIndex]['show'] = showState
        }
        
      },
      // 更新选项按钮选中信息
      updateSectionBtnsValue(modeIndex = 0, sectionIndex = -1, value = 0) {
        if (sectionIndex < 0 || sectionIndex >= this.sectionList[modeIndex]['section'].length) {
          return
        }
        // 如果showState为false则移除对应的选项按钮，否则往对应的位置添加上对应的选项按钮
        this.sectionIndex[modeIndex][sectionIndex] = {
          value,
          change: true
        }
      },
      // 选项按钮点击事件
      sectionBtnClick(index, sectionIndex) {
        // if (this.sectionIndex[this.modeIndex][index] === sectionIndex) {
        //   return
        // }
        this.$set(this.sectionIndex[this.modeIndex], index, {value: sectionIndex, change: true})
        this.$emit('click', {
          methods: this.btnsList[index]['methods'],
          index: sectionIndex,
          name: this.btnsList[index]['optional'][sectionIndex]
        })
      }
    }
  }
</script>

<style lang="scss" scoped>
  .dynamic-demo {
    padding-top: 78rpx;

    /* 顶部模式切换start */
    .mode-switch {
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-top: 75rpx;
      padding: 0 30rpx;

      &__container {
        position: relative;
        display: flex;
        flex-direction: row;
        align-items: center;
        width: 476rpx;
        height: 62rpx;
        background-color: #FFFFFF;
        box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
        border-radius: 31rpx;
      }

      &__item {
        flex: 1;
        height: 62rpx;
        width: 100%;
        line-height: 62rpx;
        text-align: center;
        font-size: 28rpx;
        color: $tn-font-sub-color;
        z-index: 2;
        transition: all 0.3s;

        &--active {
          color: #FFFFFF;
          font-weight: bold;
        }
      }

      &__slider {
        position: absolute;
        height: 62rpx;
        border-radius: 31rpx;
        // background-image: linear-gradient(-86deg, #FF8359 0%, #FFDF40 100%);
        background-image: linear-gradient(-86deg, #00C3FF 0%, #58FFF5 100%);
        box-shadow: 1rpx 10rpx 24rpx 0rpx #00C3FF77;
        z-index: 1;
        transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
      }
    }

    /* 顶部模式切换end */

    /* 演示内容展示start */
    .demo-container {
      min-height: 327rpx;
      width: calc(100% - 60rpx);
      background-color: #FFFFFF;
      box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
      margin: 0 30rpx 5rpx 30rpx;
      border-radius: 20rpx;
      position: relative;
      display: flex;
      justify-content: center;
      align-items: center;

      &--full {
        display: inline-block;
        padding-bottom: 20rpx;
        min-height: 0rpx;
        padding: 10rpx 20rpx 30rpx;
      }

      .demo {
        padding-top: 70rpx;

        &__tips {
          &__icon {
            position: absolute;
            top: 20rpx;
            right: 16rpx;
            width: 39rpx;
            height: 39rpx;
            line-height: 39rpx;
            font-size: 39rpx;

            .icon {
              background: linear-gradient(-45deg, #FF8359 0%, #FFDF40 100%);
              -webkit-background-clip: text;
              color: transparent;
              text-shadow: 0rpx 10rpx 10rpx rgba(255, 156, 82, 0.2);
            }
          }

          &__content {
            position: absolute;
            top: 65rpx;
            right: 16rpx;
            font-size: 20rpx;
            margin-left: 20rpx;
            word-wrap: normal;
            display: flex;
            flex-direction: column;
            background-color: #E6E6E6;
            padding: 20rpx;
            border-radius: 10rpx;
            transition: transform 0.3s cubic-bezier(0.68, -0.55, 0.265, 1);
            transform-origin: 0 0;
            z-index: 999999;

            &--hide {
              transform: scaleY(0);
            }

            &--show {
              transform: scaleY(100%);

              &::after {
                content: "";
                width: 0px;
                height: 0px;
                border-width: 4px;
                border-style: solid;
                border-color: transparent transparent rgba(149, 149, 149, 0.1) transparent;
                position: absolute;
                top: -8px;
                right: 6px;
              }
            }
          }
        }
      }
    }

    /* 演示内容展示end */

    /* 可选项start */
    .section-container {
      width: 100%;
      height: auto;
      margin-top: 70rpx;

      .section {
        &__content {
          margin-top: 70rpx;
          display: none;
          
          &--visible {
            display: block;
            
            &:last-child {
              padding-bottom: calc(70rpx + env(safe-area-inset-bottom));
            }
          }

          &:nth-child(1) {
            margin-top: 0rpx;
          }

          &__title {
            display: flex;
            justify-content: center;
            align-items: center;
            margin: 0 30rpx;
            text-align: center;

            &__left-line,
            &__right-line {

              width: 100rpx;
              height: 2rpx;
              position: relative;
            }

            &__left-line {
              &::after {
                content: '';
                background: inherit;
                width: 12rpx;
                height: 12rpx;
                position: absolute;
                top: -12rpx;
                right: 0rpx;
                border-radius: 50%;
                transform: translateY(50%);
              }
            }

            &__right-line {
              &::after {
                content: '';
                background: inherit;
                width: 12rpx;
                height: 12rpx;
                position: absolute;
                top: -12rpx;
                left: 0rpx;
                border-radius: 50%;
                transform: translateY(50%);
              }
            }

            &--text {
              -webkit-background-clip: text;
              color: transparent;
              min-width: 124rpx;
              height: 30rpx;
              font-size: 32rpx;
              line-height: 1;
              margin: 0 35rpx;
            }
          }

          &__btns {
            width: calc(100% - 60rpx);
            margin: 0 30rpx;
            margin-top: 29rpx;
            padding: 50rpx 30rpx 0rpx 0rpx;
            background-color: #FFFFFF;
            box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);
            border-radius: 20rpx;
            display: flex;
            flex-direction: row;
            align-items: center;
            justify-content: flex-start;
            flex-wrap: wrap;

            &__item {
              max-width: 30%;
              padding: 17rpx 36rpx;
              border-radius: 10rpx;
              margin-bottom: 40rpx;
              margin-left: 40rpx;
              position: relative;
              z-index: 1;

              // &::before {
              //   content: " ";
              //   position: absolute;
              //   top: 10rpx;
              //   left: 1rpx;
              //   width: 100%;
              //   height: 100%;
              //   background: inherit;
              //   filter: blur(24rpx);
              //   opacity: 1;
              //   z-index: -1;
              // }

              &__bg {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                border-radius: inherit;
                z-index: -1;
                opacity: 0;
                transform: scale(0);
                transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);

                &--active {
                  opacity: 1;
                  transform: scale(1);
                }
              }

              &--text {
                font-size: 24rpx;
                line-height: 1.2em;
                transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
                
                &--active {
                  color: #FFFFFF;
                }
              }
            }
          }
        }
      }
    }

    /* 可选项end */
  }
</style>
